import json
import time

computerMap={}
class Log:
    def __init__(self):
        self.timestamp=None
        self.bytes_sent=0
        self.cdn_scheme=None
        self.cookie_buvid=None
        self.cookie_sid=None
        self.cookie_userid=None
        self.http_host=None
        self.http_path=None
        self.http_referer=None
        self.http_user_agent=None
        self.request_length=0
        self.request_time=0
        self.scheme=None
        self.server_name=None
        self.status=0
        self.upstream_status=0
        self.x_backend_bili_real_ip=None

    def get_ip(self):
        return self.x_backend_bili_real_ip

    def show(self):
        print('timestamp:', type(self.timestamp), self.timestamp)
        print('bytes_sent:', type(self.bytes_sent), self.bytes_sent)
        print('cdn_scheme:', type(self.cdn_scheme), self.cdn_scheme)
        print('cookie_buvid:', type(self.cookie_buvid), self.cookie_buvid)
        print('cookie_sid:', type(self.cookie_sid), self.cookie_sid)
        print('cookie_userid:', type(self.cookie_userid), self.cookie_userid)
        print('http_host:', type(self.http_host), self.http_host)
        print('http_path:', type(self.http_path), self.http_path)
        print('http_referer:', type(self.http_referer), self.http_referer)
        print('http_user_agent:', type(self.http_user_agent), self.http_user_agent)
        print('request_length:', type(self.request_length), self.request_length)
        print('request_time:', type(self.request_time), self.request_time)
        print('scheme:', type(self.scheme), self.scheme)
        print('server_name:', type(self.server_name), self.server_name)
        print('status:', type(self.status), self.status)
        print('upstream_status:', type(self.upstream_status), self.upstream_status)
        print('x_backend_bili_real_ip:', type(self.x_backend_bili_real_ip), self.x_backend_bili_real_ip)

class Computer:
    def __init__(self):
        self.logs=[]
        self.counts=0
        self.times=[]
        self.flag=False # True代表坏的请求
        self.ip=None

    def add_log(self,log):
        self.logs.append(log)
        self.counts+=1
        self.times.append(log.timestamp)
        self.ip=log.x_backend_bili_real_ip

    def mustbeevil(self):
        self.flag=True

    def is_evil(self):
        return self.flag

    # 根据访问频率进行查找异常ip
    def time_frequency_anomaly(self,sec=30,max_count=100):
        if self.is_evil():
            return self.is_evil()
        num=len(self.times)
        if num<=2:
            return False
        self.times=sorted(self.times)
        last_time=0
        count=1
        m_count=0
        for i in range(1,num):
            l_t=int(time.mktime(self.times[i]))-sec
            count+=1
            while last_time<i and int(time.mktime(self.times[last_time]))<l_t:
                count-=1
                last_time+=1
            if count > m_count:
                m_count = count
        if(m_count>=max_count):
            l_t = int(time.mktime(self.times[0])) - sec
            print("times[0]:",int(time.mktime(self.times[0])),",l_t",l_t)
            print("ip:",self.ip,",m_count:",m_count)
            self.mustbeevil()
            return self.is_evil()
        return self.is_evil()

    def check_cookie(self):
        if self.is_evil():
            return self.is_evil()
        i=0
        logs_num=len(self.logs)
        if logs_num<=1:
            return False
        cookie_buvid=None
        cookie_sid=None
        cookie_userid=None
        while i<logs_num:
            if(self.logs[i].cookie_buvid!='-'and self.logs[i].cookie_sid!='-'and self.logs[i].cookie_userid!='-'):
                cookie_buvid=self.logs[i].cookie_buvid
                cookie_sid=self.logs[i].cookie_sid
                cookie_userid=self.logs[i].cookie_userid
                break
            else:
                i+=1
        if cookie_buvid==None or cookie_sid==None or cookie_userid==None :
            return self.is_evil()
        for i in range(logs_num):
            if  self.logs[i].cookie_buvid!=cookie_buvid and self.logs[i].cookie_sid!=cookie_sid and self.logs[i].cookie_userid!=cookie_userid:
                print("ip:",self.ip,"cookie_buvid:",self.logs[i].cookie_buvid,"cookie_sid:",self.logs[i].cookie_sid,"cookie_userid:",self.logs[i].cookie_userid,)
                self.mustbeevil()
                return self.is_evil()
        return self.is_evil()


def fileWrite(path,lines):
    with open(path,'w') as f:
        f.writelines(lines)

def showhttp_host(logs):
    http_host={}
    for i in logs:
        if i.http_host in http_host.keys():
            http_host[i.http_host]=http_host[i.http_host]+1
        else:
            http_host[i.http_host]=1
    lines=[]
    lines.append("---------------http_host---------------\n")

    for (key,value) in http_host.items():
        s = 'key:' + key + ",value:" + str(value)
        lines.append(s)
    fileWrite('./http_host.txt', lines)

    print("---------------http_host---------------")

def showhttp_referer(logs):
    http_referer={}
    for i in logs:
        if i.http_referer in http_referer.keys():
            http_referer[i.http_referer]=http_referer[i.http_referer]+1
        else:
            http_referer[i.http_referer]=1
    lines=[]
    lines.append("--------------http_referer-------------\n")
    for (key,value) in http_referer.items():
        s='key:'+key+",value:"+str(value)+'\n'
        lines.append(s)
    fileWrite('./http_referer.txt',lines)
    print("--------------http_referer-------------")

def read(path='./evil-log.log'):
    logs=[]
    with open(path) as f:
        for js in f.readlines():
            log=Log()
            js=json.loads(js)
            log.timestamp=time.strptime(js['@timestamp'],"%Y-%m-%dT%H:%M:%S+0000")
            log.bytes_sent=int(js['bytes_sent'])
            if('cdn_scheme' in js):
                log.cdn_scheme=js['cdn_scheme']
            log.cookie_buvid=js['cookie_buvid']
            log.cookie_sid=js['cookie_sid']
            log.cookie_userid=js['cookie_userid']
            log.http_host=js['http_host']
            log.http_path=js['http_path']
            log.http_referer=js['http_referer']
            log.http_user_agent = js['http_user_agent']
            log.request_length = int(js['request_length'])
            if 'request_time' in js:
                log.request_time = float(js['request_time'])
            log.scheme = js['scheme']
            log.server_name = js['server_name']
            log.status = js['status']
            log.upstream_status = js['upstream_status']
            log.x_backend_bili_real_ip = js['x_backend_bili_real_ip']
            logs.append(log)
    return logs

def addCoumputer(log):
    global computerMap
    if log.x_backend_bili_real_ip not in computerMap:
        computerMap[log.x_backend_bili_real_ip]=Computer()
    computerMap[log.x_backend_bili_real_ip].add_log(log)


def solve():
    global computerMap
    logs=read()
    print(len(logs))
    showhttp_referer(logs)
    for log in logs:
        addCoumputer(log)

    now_ip_num=len(computerMap)
    print("ip_num:",now_ip_num)
    computer_arr=computerMap.values()
    evil_ip_arr=[]
    evil_num=0
    for item in computer_arr:
        if item.time_frequency_anomaly(sec=30):
            print(evil_num,",evil_ip:",item.ip)
            evil_num+=1
            now_ip_num-=1
            evil_ip_arr.append(item.ip)
    print("after time_frequency_anomaly now evil_num:",evil_num,", now_ip_num:",now_ip_num)





    print("最后结果")
    for i in evil_ip_arr:
        print(i,end=',')
    print()


if __name__ == '__main__':
    solve()
